# 导入相关包
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt

from Main.main1 import df

# 三、用户特征探索性分析
# 查看流失用户数量和占比。
plt.figure(figsize=(10, 10))
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用黑体显示中文
# 数据
sizes = df['Churn'].value_counts()
labels = df['Churn'].value_counts().index
# 画图
plt.pie(sizes, explode=(0.1, 0), labels=labels, colors=['#4682B4', '#ADD8E6'], autopct='%1.1f%%', shadow=True)
plt.title('客户流失率')
# 展示
plt.show()
# 流失用户占比16.8%，留存用户占比83.2%，属于不平衡数据集。


# 1、用户维度特征分析
data = df.copy()
data.head()

# 1）常用登陆设备分析
fig, axes = plt.subplots(1, 2, figsize=(18, 6))
sns.countplot(data=data, x='PreferredLoginDevice', hue='Churn', palette='Blues_r', ax=axes[0])
sns.barplot(data=data, x='PreferredLoginDevice', y='Churn', palette='Blues_r', ax=axes[1])
plt.show()


# 上图中明显看出，使用Mobile Phone的用户流失数量最多，但是使用Phone的用户流失率最高。

# 定义常用登陆设备分析函数
def data_devices_analysis(df):
    login_devices = df['PreferredLoginDevice']
    login_devices_unique = login_devices.unique()

    # 提取流失用户和非流失用户的登陆设备
    churned_users = df[df['Churn'] == 1]['PreferredLoginDevice']
    churned_users_unique = churned_users.unique()

    non_churned_users = df[df['Churn'] == 0]['PreferredLoginDevice']
    non_churned_users_unique = non_churned_users.unique()

    # 统计每种登陆设备的用户数量
    device_counts_churned = pd.Series(churned_users).value_counts()  # 总数
    device_counts_non_churned = pd.Series(non_churned_users).value_counts()

    # 绘制饼图
    plt.figure(figsize=(10, 6))
    plt.pie(device_counts_churned, labels=churned_users_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Login Devices of Churned Users')
    plt.show()
    # 保存图表为图片
    # plt.savefig('./Main/picture/Login Devices of Churned Users.png', bbox_inches='tight')

    plt.figure(figsize=(10, 6))
    plt.pie(device_counts_non_churned, labels=non_churned_users_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Login Devices of Non-Churned Users')
    plt.show()
    #     plt.savefig('./Main/picture/Login Devices of Non_Churned Users.png', bbox_inches='tight')

    # 2）统计每种登陆设备的使用数量
    device_counts = pd.Series(login_devices).value_counts()

    # 绘制饼图
    plt.figure(figsize=(10, 6))
    plt.pie(device_counts, labels=login_devices_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Login Devices of All Users')
    plt.show()
    #     plt.savefig('./Main/picture/Login Devices of All Users.png', bbox_inches='tight')

    # 3）计算不同登陆设备的用户流失率
    churned_counts = churned_users.value_counts()
    churned_users_rate = churned_counts / churned_counts.sum()

    non_churned_counts = non_churned_users.value_counts()
    non_churned_users_rate = non_churned_counts / non_churned_counts.sum()

    # 绘制柱状图
    plt.figure(figsize=(10, 6))
    plt.bar(churned_users_unique, churned_users_rate, fc='r', alpha=1)
    plt.bar(non_churned_users_unique, non_churned_users_rate, bottom=churned_users_rate, fc='b', alpha=0.5)
    # 添加百分比标签
    for i in range(len(churned_users_unique)):
        plt.text(i, churned_users_rate[i] + non_churned_users_rate[i],
                 f'{churned_users_rate[i] / (churned_users_rate[i] + non_churned_users_rate[i]) * 100}%', ha='center')
    plt.title('Churn Users and No Churn Users Percentages by Login Device')
    plt.xlabel('Login Device')
    plt.ylabel('Churn Rate')
    plt.legend(['Churn Users', 'No Churn Users'])
    plt.show()


#     plt.savefig('./Main/picture/Churn Users and No Churn Users Percentages by Login Device.png', bbox_inches='tight')

# 主函数
if __name__ == '__main__':
    df = df
    data_devices_analysis(df)

# 结论指出，使用 Mobile Phone 的总用户数最多，但 Pad 和 Phone 的流失用户占比较高。
# 建议产品团队测试 Pad 和 Phone 终端的产品稳定性。

# 2）城市等级分析
fig, axes = plt.subplots(1, 2, figsize=(18, 6))
sns.countplot(data=data, x='CityTier', hue='Churn', palette='Blues_r', ax=axes[0])
sns.barplot(data=data, x='CityTier', y='Churn', palette='Blues_r', ax=axes[1])
plt.show()


# 上图中明显看出，1级城市流失人数最多，但是3级城市的用户流失率更高。

# 定义城市等级分析函数：
def data_city_analysis(df):
    city_tiers = df['CityTier']
    city_tiers_unique = city_tiers.unique()

    # 统计每种城市等级的用户数量
    city_counts = pd.Series(city_tiers).value_counts()

    # 绘制饼图
    plt.figure(figsize=(10, 6))
    plt.pie(city_counts, labels=city_tiers_unique, autopct='%1.1f%%', startangle=90)
    plt.title('City Tiers')
    plt.show()

    # 2）城市等级与流失用户分析
    churned_users = df[df['Churn'] == 1]['CityTier']
    churned_counts = pd.Series(churned_users).value_counts()

    # 绘制饼图
    plt.figure(figsize=(10, 6))
    plt.pie(churned_counts, labels=city_tiers_unique, autopct='%1.1f%%', startangle=90)
    plt.title('City Tiers of Churned Users')
    plt.show()

    # 3）城市等级与非流失用户分析
    non_churned_users = df[df['Churn'] == 0]['CityTier']
    non_churned_counts = pd.Series(non_churned_users).value_counts()

    # 绘制饼图
    plt.figure(figsize=(10, 6))
    plt.pie(non_churned_counts, labels=city_tiers_unique, autopct='%1.1f%%', startangle=90)
    plt.title('City Tiers of Non-Churned Users')
    plt.show()

    # 4）城市等级整体分析
    churned_users_unique = churned_users.unique()
    churned_counts = churned_users.value_counts()
    churned_users_rate = churned_counts / churned_counts.sum()

    non_churned_users_unique = non_churned_users.unique()
    non_churned_counts = non_churned_users.value_counts()
    non_churned_users_rate = non_churned_counts / non_churned_counts.sum()

    # 绘制柱状图
    plt.figure(figsize=(10, 6))
    plt.bar(churned_users_unique, churned_users_rate, color='r', alpha=1)
    plt.bar(non_churned_users_unique, non_churned_users_rate, bottom=churned_users_rate, color='b', alpha=0.5)
    # 添加百分比标签
    for i in range(1, len(churned_users_unique) + 1):
        plt.text(i, churned_users_rate[i] + 0.1,
                 f'{churned_users_rate[i] / (churned_users_rate[i] + non_churned_users_rate[i]) * 100}%', ha='center')
    plt.title('Churn Users and No Churn Users Percentages by City Tiers')
    plt.xlabel('City Tiers')
    plt.ylabel('Churn Rate')
    plt.legend(['Churn Users', 'No Churn Users'], loc='upper center')
    plt.show()


# 主函数
if __name__ == '__main__':
    df = df
    data_city_analysis(df)
# 结论：城市等级为3的流失用户占比为57.3%，城市等级为2的流失用户占比为55.0%，远高于城市等级为1的45.6%。
# 建议运营团队在城市等级为2和3的城市适当开展运营活动（如鼓励城市特色作品直播等），提高用户粘性。

# 3）性别分析
plt.rcParams['font.size'] = '16'
fig, axes = plt.subplots(1, 2, figsize=(18, 6))
sns.countplot(x='Gender', hue='Churn', data=data, palette='Blues_r', ax=axes[0])
sns.barplot(data=data, x='Gender', y='Churn', palette='Blues_r', ax=axes[1])
plt.show()


# 从上图中明显看出，性别与用户流失有差异，男性流失数量更高一些，并且流失率也更高。

# 定义性别分析函数
def data_gender_analysis(df):
    genders = df['Gender']
    genders_unique = genders.unique()

    # 统计每种性别的用户数量
    gender_counts = pd.Series(genders).value_counts()

    # 绘制饼图
    plt.figure()
    plt.pie(gender_counts, labels=genders_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Gender')
    plt.show()

    # 2）性别与流失用户分析
    churned_users = df[df['Churn'] == 1]['Gender']
    churned_counts = pd.Series(churned_users).value_counts()

    # 绘制饼图
    plt.figure()
    plt.pie(churned_counts, labels=genders_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Gender of Churned Users')
    plt.show()

    # 3）性别与非流失用户分析
    non_churned_users = df[df['Churn'] == 0]['Gender']
    non_churned_counts = pd.Series(non_churned_users).value_counts()

    # 绘制饼图
    plt.figure()
    plt.pie(non_churned_counts, labels=genders_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Gender of Non-Churned Users')
    plt.show()

    # 4）性别整体分析
    churned_users_unique = churned_users.unique()
    churned_counts = churned_users.value_counts()
    churned_users_rate = churned_counts / churned_counts.sum()

    non_churned_users_unique = non_churned_users.unique()
    non_churned_counts = non_churned_users.value_counts()
    non_churned_users_rate = non_churned_counts / non_churned_counts.sum()

    # 绘制柱状图
    plt.figure(figsize=(10, 6))
    plt.bar(churned_users_unique, churned_users_rate, color='r', alpha=1)
    plt.bar(non_churned_users_unique, non_churned_users_rate, color='b', alpha=0.5)
    # 添加百分比标签
    for i in range(len(churned_users_unique)):
        plt.text(i, churned_users_rate[i],
                 f'{churned_users_rate[i] / (churned_users_rate[i] + non_churned_users_rate[i]) * 100}%', ha='center',
                 va='bottom', fontsize=15)
    plt.title('Churn Users and No Churn Users Percentages by Gender')
    plt.xlabel('Gender')
    plt.ylabel('Churn Rate')
    plt.legend(['Churn Users', 'No Churn Users'])
    plt.show()


# 主函数
if __name__ == '__main__':
    df = df
    data_gender_analysis(df)
# 结论：女性用户是平台的主要用户，女性的流失用户占比为47.5%，男性的流失用户占比为51.6%，基本持平。
# 建议运营团队根据男性与女性喜欢的直播风格，进行直播内容定向推送，尝试降低其流失率。

# 4）年龄分析
fig, axes = plt.subplots(1, 2, figsize=(18, 6))
sns.countplot(data=data, x='AgeGroup', hue='Churn', palette='Blues_r', ax=axes[0])
sns.barplot(data=data, x='AgeGroup', y='Churn', palette='Blues_r', ax=axes[1])
plt.show()


# 从上图明显看出，相较于其他年龄段的用户而言，60岁以上的老年人用户数量较少，但老年用户的流失率要远远高于其他年龄用户。

# 定义年龄分析函数
def data_ages_analysis(df):
    ages = df['AgeGroup']
    ages_unique = ages.unique()

    # 统计每种年龄的用户数量
    ages_counts = pd.Series(ages).value_counts()

    # 绘制饼图
    plt.figure(figsize=(10, 6))
    plt.pie(ages_counts, labels=ages_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Age Groups')
    plt.show()

    # 2）年龄与流失用户分析
    churned_users = df[df['Churn'] == 1]['AgeGroup']
    churned_counts = pd.Series(churned_users).value_counts()

    # 绘制饼图
    plt.figure(figsize=(10, 6))
    plt.pie(churned_counts, labels=ages_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Age Groups of Churned Users')
    plt.show()

    # 3）年龄与非流失用户分析
    non_churned_users = df[df['Churn'] == 0]['AgeGroup']
    non_churned_counts = pd.Series(non_churned_users).value_counts()

    # 绘制饼图
    plt.figure(figsize=(10, 6))
    plt.pie(non_churned_counts, labels=ages_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Age Groups of Non-Churned Users')
    plt.show()

    # 4）年龄整体分析
    churned_users_unique = churned_users.unique()
    churned_counts = churned_users.value_counts()
    churned_users_rate = churned_counts / churned_counts.sum()

    non_churned_users_unique = non_churned_users.unique()
    non_churned_counts = non_churned_users.value_counts()
    non_churned_users_rate = non_churned_counts / non_churned_counts.sum()

    # 绘制柱状图
    plt.figure(figsize=(10, 6))
    plt.bar(churned_users_unique, churned_users_rate, color='r', alpha=1)
    plt.bar(non_churned_users_unique, non_churned_users_rate, color='b', alpha=0.5)
    # 添加百分比标签
    for i in range(1, len(churned_users_unique) + 1):
        plt.text(i, non_churned_users_rate[i],
                 f'{churned_users_rate[i] / (churned_users_rate[i] + non_churned_users_rate[i]) * 100}%', ha='center')
    plt.title('Churn Users and No Churn Users Percentages by Age Groups')
    plt.xlabel('Age Groups')
    plt.ylabel('Churn Rate')
    plt.legend(['Churn Users', 'No Churn Users'])
    plt.show()


# 主函数
if __name__ == '__main__':
    df = df
    data_ages_analysis(df)
# 结论：年龄分组为6的流失用户占比最高，为72.3%，其次是年龄分组为5，流失用户占比为58.9%。
# 建议运营团队鼓励更多年龄分组为5和6喜欢的直播内容和商品进驻，提高其留存率。

# 5）婚姻状况分析
fig, axes = plt.subplots(1, 2, figsize=(18, 6))
sns.countplot(data=data, x='MaritalStatus', hue='Churn', palette='Blues_r', ax=axes[0])
sns.barplot(data=data, x='MaritalStatus', y='Churn', palette='Blues_r', ax=axes[1])
plt.show()


# 上图中明显看出，单身的用户中流失人数最多，并且流失率最高。

# 定义婚姻状况函数
def data_matrital_analysis(df):
    marital_statuses = df['MaritalStatus']
    marital_statuses_unique = marital_statuses.unique()

    # 统计每种婚姻状况的用户数量
    marital_counts = pd.Series(marital_statuses).value_counts()

    # 绘制饼图
    plt.figure(figsize=(10, 6))
    plt.pie(marital_counts, labels=marital_statuses_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Marital Status')
    plt.show()

    # 2）婚姻状况与流失用户分析
    churned_users = df[df['Churn'] == 1]['MaritalStatus']
    churned_counts = pd.Series(churned_users).value_counts()

    # 绘制饼图
    plt.figure(figsize=(10, 6))
    plt.pie(churned_counts, labels=marital_statuses_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Marital Status of Churned Users')
    plt.show()

    # 3）婚姻状况与非流失用户分析
    non_churned_users = df[df['Churn'] == 0]['MaritalStatus']
    non_churned_counts = pd.Series(non_churned_users).value_counts()

    # 绘制饼图
    plt.figure(figsize=(10, 6))
    plt.pie(non_churned_counts, labels=marital_statuses_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Marital Status of Non-Churned Users')
    plt.show()

    # 4）婚姻状况整体分析
    churned_users_unique = churned_users.unique()
    churned_counts = churned_users.value_counts()
    churned_users_rate = churned_counts / churned_counts.sum()

    non_churned_users_unique = non_churned_users.unique()
    non_churned_counts = non_churned_users.value_counts()
    non_churned_users_rate = non_churned_counts / non_churned_counts.sum()

    # 绘制柱状图
    plt.figure(figsize=(10, 6))
    plt.bar(churned_users_unique, churned_users_rate, color='r', alpha=1)
    plt.bar(non_churned_users_unique, non_churned_users_rate, color='b', alpha=0.5)
    # 添加百分比标签
    for i in range(len(churned_users_unique)):
        plt.text(i, churned_users_rate[i] + 0.05,
                 f'{churned_users_rate[i] / (churned_users_rate[i] + non_churned_users_rate[i]) * 100}%', ha='center')
    plt.title('Churn Users and No Churn Users Percentages by Marital Status')
    plt.xlabel('Marital Status')
    plt.ylabel('Churn Rate')
    plt.legend(['Churn Users', 'No Churn Users'])
    plt.show()


# 主函数
if __name__ == '__main__':
    df = df
    data_matrital_analysis(df)
# 结论：单身的总用户数最多，且流失用户占比较低，是产品的优质用户群，离异的流失用户占比较高，为56.4%，远高于单身和已婚的用户。
# 建议运营团队在挖掘新用户时，更注意去吸引单身的用户，对于现有的离异用户，采取积极留存措施。

# 6）上月首选订单类型分析
fig, axes = plt.subplots(1, 2, figsize=(18, 6))
sns.countplot(data=data, x='PreferedOrderCat', hue='Churn', palette='Blues_r', ax=axes[0])
sns.barplot(data=data, x='PreferedOrderCat', y='Churn', palette='Blues_r', ax=axes[1])
plt.show()


# 上图中明显看出，Mobile Phone的流失人数最多，并且用户流失率也最高。

# 定义上月首选订单类型分析函数
def data_preferedordercat_analysis(df):
    order_cats = df['PreferedOrderCat']
    order_cats_unique = order_cats.unique()

    # 统计每种上月首选订单类型的用户数量
    cat_counts = pd.Series(order_cats).value_counts()

    # 绘制饼图展示上月首选订单类型分布
    plt.figure(figsize=(10, 6))
    plt.pie(cat_counts, labels=order_cats_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Order Cats')
    plt.show()

    # 2）上月订单情况与流失用户分析
    churned_users = df[df['Churn'] == 1]['PreferedOrderCat']
    churned_counts = pd.Series(churned_users).value_counts()

    # 绘制饼图示上月流失用户的订单类型分布
    plt.figure(figsize=(10, 6))
    plt.pie(churned_counts, labels=order_cats_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Order Cats of Churned Users')
    plt.show()

    # 3）上月订单情况与非流失用户分析
    non_churned_users = df[df['Churn'] == 0]['PreferedOrderCat']
    non_churned_counts = pd.Series(non_churned_users).value_counts()

    # 绘制饼图展示上月非流失用户的订单类型分布
    plt.figure(figsize=(10, 6))
    plt.pie(non_churned_counts, labels=order_cats_unique, autopct='%1.1f%%', startangle=90)
    plt.title('Order Cats of Non-Churned Users')
    plt.show()

    # 4）上月订单情况整体分析
    churned_users_unique = churned_users.unique()
    churned_counts = churned_users.value_counts()
    churned_users_rate = churned_counts / churned_counts.sum()

    non_churned_users_unique = non_churned_users.unique()
    non_churned_counts = non_churned_users.value_counts()
    non_churned_users_rate = non_churned_counts / non_churned_counts.sum()

    # 绘制柱状图展示上月不同订单类型的用户流失率
    plt.figure(figsize=(10, 6))
    plt.bar(churned_users_unique, churned_users_rate, color='r', alpha=1)
    plt.bar(non_churned_users_unique, non_churned_users_rate, color='b', alpha=0.5)
    # 添加百分比标签
    for i in range(len(churned_users_unique)):
        plt.text(i, non_churned_users_rate[i],
                 f'{churned_users_rate[i] / (churned_users_rate[i] + non_churned_users_rate[i]) * 100}%', ha='center')
    plt.title('Churn Users and No Churn Users Percentages by Order Cats of Churned Users')
    plt.xlabel('Order Cats of Churned Users')
    plt.ylabel('Churn Rate')
    plt.legend(['Churn Users', 'No Churn Users'])
    plt.show()


if __name__ == '__main__':
    df = df
    data_preferedordercat_analysis(df)
# 结论：月主要订单为Mobile Phone和Household的流失用户占比较多，均超过了50%，其次是上月订单为Others的用户。
# 可能是由于Mobile Phone和Household的商品使用周期较长，用户购买该类商品后，很长一段时间不再有相同的购买意愿，从而造成用户流失。

# 7）使用时长对流失的影响
# HourSpendOnApp:用户使用时长,单位(小时)
plt.figure(figsize=(9, 4))
g = sns.kdeplot(data['HourSpendOnApp'][(data['Churn'] == 0)], color='green', shade=True)
g = sns.kdeplot(data['HourSpendOnApp'][(data['Churn'] == 1)], ax=g, color='orange', shade=True)
g.set_xlabel('HourSpendOnApp')
g.set_ylabel('Frequency')
plt.title('时长与流失的关系图')
g.legend(['未流失', '流失'])
plt.show()
# 从上图中明显看出，使用时长越久流失率越低，符合一般经验；流失率在3小时左右是最高的。
# 看来3小时是个很关键的分水岭，要注重这段时间用户的维护，以降低流失率。

## 2、用户行为特征分析

# 将性别属性转换为 0 和 1，女性为 0，男性为 1
df['Gender'] = pd.factorize(df['Gender'])[0]

# 提取各项特征和流失标签
features = df[['Tenure', 'WarehouseToHome', 'AgeGroup', 'Gender', 'HourSpendOnApp', 'OrderCount',
               'OrderAmountHikeFromlastYear', 'DaySinceLastOrder', 'CouponUsed',
               'NumberOfStreamerFollowed', 'SatisfactionScore', 'DiscountAmount']]
churn = df['Churn']

# 计算用户行为特征的平均值和标准差
average_values = features.mean()
std_values = features.std()

# 打印平均值和标准差
print('Average Values:')
print(average_values)
print()
print('Standard Deviation Values:')
print(std_values)

# 绘制箱线图
for feature in features.columns:
    plt.subplot(3, 4, features.columns.get_loc(feature) + 1)
    plt.boxplot([df[churn == 0][feature], df[churn == 1][feature]], labels=['non_Churned Users', 'Churned Users'])
    plt.title(f'Boxplot for {feature}')
    plt.xlabel('churned?')
    plt.ylabel('Values')
    plt.legend()
    plt.tight_layout()
    plt.show()

# 观察用户流失与各个维度之间的关系
df_onehot = pd.get_dummies(df.iloc[:, 1:19])
df_onehot.head()
plt.figure(figsize=(15, 4))
df_onehot.corr()['Churn'].sort_values(ascending=False).plot(kind='bar')
plt.title('用户流失与各个维度之间的关系')
